<template lang="html">
  <el-input
    class="rb-number-input"
    ref="input"
    v-model="currentValue"
    :disabled="disabled"
    :clearable="!disabled"
    @paste.native="returnFunc"
    @keydown.native="handleKeyDown">
  </el-input>
</template>

<script>

export default {
  props: {
    value: {
      default: null
    },
    maxlength: {
      type: Number,
      default: 14
    },
    decimal: {
      type: Number,
      default: 2
    },
    max: {
      type: Number,
      default: Infinity
    },
    min: {
      type: Number,
      default: -Infinity
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      currentValue: '',
      beforeValue: null,
      allowKeys: [
        // 允许输入的字符
        '-',
        '.',
        '0',
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',

        // 光标移动
        'Home',
        'End',
        'PageUp',
        'PageDown',
        'Tab',
        'Left', // IE
        'Right', // IE
        'Up', // IE
        'Down', // IE
        'ArrowLeft', // 非IE
        'ArrowRight', // 非IE
        'ArrowUp', // 非IE
        'ArrowDown', // 非IE

        // 删除操作
        'Backspace',
        'Delete',

        'F1',
        'F2',
        'F3',
        'F4',
        'F5',
        'F6',
        'F7',
        'F8',
        'F9',
        'F10',
        'F11',
        'F12'
      ]
    }
  },
  watch: {
    value: {
      immediate: true,
      handler (value) {
        if (!this.beforeValue) {
          this.currentValue = (value && typeof value !== 'number') ? value.replace(/(\..*[^0])0*$/g, '$1').replace(/\.0*0$/g, '') : value
        } else {
          this.currentValue = value
        }
      }
    },
    currentValue (value) {
      if (isNaN((!!value || value === 0) ? Number(value) : null) && value !== '-') {
        // 若输入汉字 拦截。
        this.$message({
          type: 'error',
          message: this.$t('validate.illegalCharacter')
        })
        setTimeout(() => {
          this.currentValue = this.beforeValue
        }, 0)
      } else {
        // 将当前值记录到beforeValue中
        let newValue = (!!value || value === 0 || value === '0') ? value : null
        if (typeof Number(newValue) === 'number' && this.min >= 0 && String(newValue).indexOf('-') > -1) {
          setTimeout(() => {
            this.currentValue = String(newValue).replace('-', '')
            this.$message({
              type: 'error',
              message: this.$t('message.mustBeAPositive')
            })
          }, 0)
        } else {
          this.$emit('input', newValue)
          this.$emit('change', newValue)
          this.beforeValue = newValue
        }
      }
    }
  },
  computed: {
    integerLength () {
      return String(isNaN(Math.abs(parseInt(this.currentValue))) ? '' : Math.abs(parseInt(this.currentValue))).length
    },
    decimalLength () {
      let stringCurrentValue = String(this.currentValue)
      return stringCurrentValue.split('.')[1] ? stringCurrentValue.split('.')[1].length : 0
    }
  },
  methods: {
    returnFunc (event) {
      if (typeof event.stopPropagation === 'function') {
        event.stopPropagation()
      } else {
        event.cancelBubble = true
      }
      if (typeof event.preventDefault === 'function') {
        event.preventDefault()
      } else {
        event.returnValue = false
      }
    },
    handleKeyDown (event) {
      // 获取当前光标位置
      let cursorStart = this.$el.children[0].selectionStart
      let cursorEnd = this.$el.children[0].selectionEnd

      // 如果光标是多选 则禁用
      if (cursorStart !== cursorEnd && !((cursorEnd - cursorStart === (this.currentValue ? String(this.currentValue).length : 0)) && ['Backspace', 'Delete'].indexOf(event.key) > -1)) {
        return this.returnFunc(event)
      }

      // 获取"."所在位置
      let pointPosition = String(this.currentValue).indexOf('.')
      // 只能输入允许范围内的key
      if (this.allowKeys.indexOf(event.key) === -1) {
        return this.returnFunc(event)
      }

      // 不允许重复输入"."，且"."不能输入在第一位或最后 小数位满了 之前
      if (event.key === '.' && event.keyCode && (this.decimal === 0 || pointPosition >= 0 || cursorStart === 0 || cursorStart < String(this.currentValue).length - this.decimal)) {
        return this.returnFunc(event)
      }

      // 删除"."时 需要判断整数位会不会超长
      if (event.key === 'Backspace' && (cursorStart - pointPosition === 1) && (this.integerLength + this.decimalLength > this.maxlength - this.decimal)) {
        return this.returnFunc(event)
      } else if (event.key === 'Delete' && (cursorStart === pointPosition) && (this.integerLength + this.decimalLength > this.maxlength - this.decimal)) {
        return this.returnFunc(event)
      }

      // 负号不允许重复，并且只允许在第一位输入，当设min时 不允许输 '-'
      if (event.key === '-' && (this.min >= 0 || String(this.currentValue).indexOf('-') >= 0 || cursorStart > 0)) {
        return this.returnFunc(event)
      }

      // 在负号前边不允许再输入数字
      if ('0123456789'.indexOf(event.key) > -1 && cursorStart <= String(this.currentValue).indexOf('-')) {
        return this.returnFunc(event)
      }

      // 整数部分长度检测
      // 如果整数为长度超过12 则只能输入12位整数
      if ('0123456789'.indexOf(event.key) > -1 && (pointPosition === -1 || cursorStart <= pointPosition) && (this.integerLength >= (this.maxlength - this.decimal))) {
        return this.returnFunc(event)
      }

      // 小数部分长度检测
      if ('0123456789'.indexOf(event.key) > -1 && pointPosition > -1 && (cursorStart > pointPosition) && (this.decimalLength >= this.decimal)) {
        return this.returnFunc(event)
      }
    }
  }
}

</script>
